package Fanlevel

import (
	"github.com/bitly/go-simplejson"
)

//包含了20个通风等级
type FanLevelAllStruct struct {
	LvStOneLen       byte               //一个通风等级结构体的长度
	LvStGapDevLen    byte               //单个通风结构体里面GapDev的长度，是由20个里面取最长的
	LvStOpenDevSOLen byte               //单个通风结构体里面OpenDevSO的长度，是由20个里面取最长的
	LvStSpellDev     byte               //单个通风结构体里面SpellDev的长度，是由20个里面取最长的
	LvStCurtainLen   byte               //单个通风结构体里面CurtainNUMv的长度，是由20个里面取最长的
	LvStIvFanLen     byte               //同上
	AllFanLevelArry  [20]FanLevelStruct //20个通风等级
}

//包含了单个通风等级结构体
type FanLevelStruct struct {
	Tem_Diff        uint16 //长度2                  温差，如果相差12.3度那么就是123数值
	GapDev          []byte //长度LvStGapDevLen字段 间断设备
	GapDevOpenTime  byte   //长度1                  间断设备开启的时间，单个周期的长度在设置结构体中
	OpenDevSO       []byte //长度LvStOpenDevSOLen   单向设备的开启列表
	SpellDev        []byte //长度LvStSpellDev       轮询式开启的设备
	CurtainNUM      []byte //长度LvStCurtainLen     想打开的双向设备，
	CurtainPosition byte   //长度1                  双向设备打开的百分比 上面的卷帘设备打开按这个百分比
	IvFanNum        []byte //长度LvStIvFanLen       变速设备列表
	IvFanValue      byte   //长度1                  变速设备开启的值
}

//根据解析到的json中的curtain_set字段来为单个通风结构体的双向设备启动赋值
func (fl *FanLevelAllStruct) SetCurtain(js *simplejson.Json) {
	jsarry, _ := js.Array() //传入的json是一个数组
	//json里面需要修改的通风等级个数
	for i := 0; i < len(jsarry); i++ {
		lv, _ := js.GetIndex(i).Get("lv").Int() //获取这个json里面设置的是哪个通风等级
		//按照json的要求将这个通风等级里面卷帘开启的百分比改为他的要求
		do_persent, _ := js.GetIndex(i).Get("position").Int()
		fl.AllFanLevelArry[lv].CurtainPosition = byte(do_persent)
		do_arry, _ := js.GetIndex(i).Get("curtain_set").Array()
		//单个通风等级里面需要添加的双向设备
		for j := 0; j < len(do_arry); j++ {
			do_i, _ := js.GetIndex(i).Get("curtain_set").GetIndex(j).Int()
			by := byte(do_i)
			fl.AllFanLevelArry[lv].CurtainNUM = append(fl.AllFanLevelArry[lv].CurtainNUM, by)
		}
	}
}

//根据解析到的json中的ivfan_set字段来为单个通风结构体的双向设备启动赋值
func (fl *FanLevelAllStruct) SetIvFan(js *simplejson.Json) {
	jsarry, _ := js.Array() //传入的json是一个数组
	//json里面需要修改的通风等级个数
	for i := 0; i < len(jsarry); i++ {
		lv, _ := js.GetIndex(i).Get("lv").Int() //获取这个json里面设置的是哪个通风等级
		//按照json的要求将这个通风等级里面卷帘开启的百分比改为他的要求
		do_persent, _ := js.GetIndex(i).Get("value").Int()
		fl.AllFanLevelArry[lv].IvFanValue = byte(do_persent)
		do_arry, _ := js.GetIndex(i).Get("ivfan_dev").Array()
		//单个通风等级里面需要添加的变速设备
		for j := 0; j < len(do_arry); j++ {
			do_i, _ := js.GetIndex(i).Get("ivfan_dev").GetIndex(j).Int()
			by := byte(do_i)
			fl.AllFanLevelArry[lv].IvFanNum = append(fl.AllFanLevelArry[lv].IvFanNum, by)
		}
	}
}

//根据解析到的json中的lv_set字段来为单个通风结构体的启动赋值
//结构体赋值：1间断设备列表 2.单向设备列表 3.温差 4.轮询设备列表
func (fl *FanLevelAllStruct) SetLv(js *simplejson.Json) {
	jsarry, _ := js.Array() //传入的json是一个数组
	//json里面需要修改的通风等级个数
	for i := 0; i < len(jsarry); i++ {
		lv, _ := js.GetIndex(i).Get("lv").Int() //获取这个json里面设置的是哪个通风等级

		//温差
		temp_diff, _ := js.GetIndex(i).Get("temp_diff").Float64()
		fl.AllFanLevelArry[lv].Tem_Diff = uint16(temp_diff * 10) //按照10倍存储

		//间断设备
		gap_dev_array, _ := js.GetIndex(i).Get("gap_dev").Array()
		for j := 0; j < len(gap_dev_array); j++ {
			do_i, _ := js.GetIndex(i).Get("gap_dev").GetIndex(j).Int()
			by := byte(do_i)
			fl.AllFanLevelArry[lv].GapDev = append(fl.AllFanLevelArry[lv].GapDev, by)
		}

		//一个周期内间断设备开启的时间
		gap_open_time, _ := js.GetIndex(i).Get("open_time").Int()
		fl.AllFanLevelArry[lv].GapDevOpenTime = byte(gap_open_time)

		//单向设备
		open_dev_array, _ := js.GetIndex(i).Get("open_dev").Array()
		for j := 0; j < len(open_dev_array); j++ {
			do_i, _ := js.GetIndex(i).Get("open_dev").GetIndex(j).Int()
			by := byte(do_i)
			fl.AllFanLevelArry[lv].OpenDevSO = append(fl.AllFanLevelArry[lv].OpenDevSO, by)
		}

		//轮询设备
		spell_dev_array, _ := js.GetIndex(i).Get("spell_dev").Array()
		for j := 0; j < len(spell_dev_array); j++ {
			do_i, _ := js.GetIndex(i).Get("spell_dev").GetIndex(j).Int()
			by := byte(do_i)
			fl.AllFanLevelArry[lv].SpellDev = append(fl.AllFanLevelArry[lv].SpellDev, by)
		}
	}
}

//计算20个通风等级中的每一个等级中的CurtainNUM切片，找到20个等级中CurtainNUM的最大长度
//然后20个等级中的CurtainNUM在后面补0全部统一为最大长度
//返回：OpenSODev的最大长度
//小写开头代表私有
func (fl *FanLevelAllStruct) cal_CurtainNUM_Maxlen_and_set0() int {
	var maxlen = 0
	//20个等级,求最大
	for i := 0; i < 20; i++ {
		if len(fl.AllFanLevelArry[i].CurtainNUM) > maxlen {
			maxlen = len(fl.AllFanLevelArry[i].CurtainNUM)
		}
	}
	//补0
	for i := 0; i < 20; i++ {
		var zeroNum = maxlen - len(fl.AllFanLevelArry[i].CurtainNUM) //要补0的长度
		if zeroNum != 0 {
			var zeroArry = make([]byte, zeroNum)
			fl.AllFanLevelArry[i].CurtainNUM = append(fl.AllFanLevelArry[i].CurtainNUM, zeroArry...)
		}
	}
	return maxlen
}

//计算20个通风等级中的每一个等级中的IvFanNum切片，找到20个等级中IvFanNum的最大长度
//然后20个等级中的IvFanNum在后面补0全部统一为最大长度
//返回：IvFanNum的最大长度
//小写开头代表私有
func (fl *FanLevelAllStruct) cal_IvFanNum_Maxlen_and_set0() int {
	var maxlen = 0
	//20个等级,求最大
	for i := 0; i < 20; i++ {
		if len(fl.AllFanLevelArry[i].IvFanNum) > maxlen {
			maxlen = len(fl.AllFanLevelArry[i].IvFanNum)
		}
	}
	//补0
	for i := 0; i < 20; i++ {
		var zeroNum = maxlen - len(fl.AllFanLevelArry[i].IvFanNum) //要补0的长度
		if zeroNum != 0 {
			var zeroArry = make([]byte, zeroNum)
			fl.AllFanLevelArry[i].IvFanNum = append(fl.AllFanLevelArry[i].IvFanNum, zeroArry...)
		}
	}
	return maxlen
}

//计算20个通风等级中的每一个等级中的GapDev切片，找到20个等级中GapDev的最大长度
//然后20个等级中的GapDev在后面补0全部统一为最大长度
//返回：GapDev的最大长度
//小写开头代表私有
func (fl *FanLevelAllStruct) cal_GapDev_Maxlen_and_set0() int {
	var maxlen = 0
	//20个等级,求最大
	for i := 0; i < 20; i++ {
		if len(fl.AllFanLevelArry[i].GapDev) > maxlen {
			maxlen = len(fl.AllFanLevelArry[i].GapDev)
		}
	}
	//补0
	for i := 0; i < 20; i++ {
		var zeroNum = maxlen - len(fl.AllFanLevelArry[i].GapDev) //要补0的长度
		if zeroNum != 0 {
			var zeroArry = make([]byte, zeroNum)
			fl.AllFanLevelArry[i].GapDev = append(fl.AllFanLevelArry[i].GapDev, zeroArry...)
		}
	}
	return maxlen
}

//计算20个通风等级中的每一个等级中的OpenDevSO切片，找到20个等级中OpenDevSO的最大长度
//然后20个等级中的OpenDevSO在后面补0全部统一为最大长度
//返回：OpenDevSO的最大长度
//小写开头代表私有
func (fl *FanLevelAllStruct) cal_OpenDevSO_Maxlen_and_set0() int {
	var maxlen = 0
	//20个等级,求最大
	for i := 0; i < 20; i++ {
		if len(fl.AllFanLevelArry[i].OpenDevSO) > maxlen {
			maxlen = len(fl.AllFanLevelArry[i].OpenDevSO)
		}
	}
	//补0
	for i := 0; i < 20; i++ {
		var zeroNum = maxlen - len(fl.AllFanLevelArry[i].OpenDevSO) //要补0的长度
		if zeroNum != 0 {
			var zeroArry = make([]byte, zeroNum)
			fl.AllFanLevelArry[i].OpenDevSO = append(fl.AllFanLevelArry[i].OpenDevSO, zeroArry...)
		}
	}
	return maxlen
}

//计算20个通风等级中的每一个等级中的SpellDev切片，找到20个等级中SpellDev的最大长度
//然后20个等级中的SpellDev在后面补0全部统一为最大长度
//返回：OpenDevSO的最大长度
//小写开头代表私有
func (fl *FanLevelAllStruct) cal_SpellDev_Maxlen_and_set0() int {
	var maxlen = 0
	//20个等级,求最大
	for i := 0; i < 20; i++ {
		if len(fl.AllFanLevelArry[i].SpellDev) > maxlen {
			maxlen = len(fl.AllFanLevelArry[i].SpellDev)
		}
	}
	//补0
	for i := 0; i < 20; i++ {
		var zeroNum = maxlen - len(fl.AllFanLevelArry[i].SpellDev) //要补0的长度
		if zeroNum != 0 {
			var zeroArry = make([]byte, zeroNum)
			fl.AllFanLevelArry[i].SpellDev = append(fl.AllFanLevelArry[i].SpellDev, zeroArry...)
		}
	}
	return maxlen
}

//计算通风等级结构体的长度（单项和总）
func (fl *FanLevelAllStruct) CalSTLen() {
	fl.LvStGapDevLen = byte(fl.cal_GapDev_Maxlen_and_set0())
	fl.LvStOpenDevSOLen = byte(fl.cal_OpenDevSO_Maxlen_and_set0())
	fl.LvStSpellDev = byte(fl.cal_SpellDev_Maxlen_and_set0())
	fl.LvStCurtainLen = byte(fl.cal_CurtainNUM_Maxlen_and_set0())
	fl.LvStIvFanLen = byte(fl.cal_IvFanNum_Maxlen_and_set0())
	fl.LvStOneLen = 2 + fl.LvStGapDevLen + 1 + fl.LvStOpenDevSOLen + fl.LvStSpellDev + fl.LvStCurtainLen + 1 + fl.LvStIvFanLen + 1
}

//单个通风等级结构体转化为bytes
func (ofl *FanLevelStruct) tobytes() []byte {
	b := []byte{}
	//注意这个uint16是按照大端来的
	b = append(b, byte(ofl.Tem_Diff))    //uint16的低位
	b = append(b, byte(ofl.Tem_Diff>>8)) //uint16的高位
	b = append(b, ofl.GapDev...)
	b = append(b, ofl.GapDevOpenTime)
	b = append(b, ofl.OpenDevSO...)
	b = append(b, ofl.SpellDev...)
	b = append(b, ofl.CurtainNUM...)
	b = append(b, ofl.CurtainPosition)
	b = append(b, ofl.IvFanNum...)
	b = append(b, ofl.IvFanValue)
	return b
}

//将通风等级结构体转换为bytes
func (fl *FanLevelAllStruct) Tobytes() []byte {
	b := []byte{}
	b = append(b, fl.LvStOneLen)
	b = append(b, fl.LvStGapDevLen)
	b = append(b, fl.LvStOpenDevSOLen)
	b = append(b, fl.LvStSpellDev)
	b = append(b, fl.LvStCurtainLen)
	b = append(b, fl.LvStIvFanLen)
	for i := 0; i < 20; i++ {
		b = append(b, fl.AllFanLevelArry[i].tobytes()...)
	}
	return b
}
